﻿using System;
using System.IO;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using ESRI.ArcGIS.ArcMapUI;
using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.Display;
using ESRI.ArcGIS.Framework;
using ESRI.ArcGIS.Geometry;
using ESRI.ArcGIS.Output;
using ESRI.ArcGIS.Geodatabase;
//using ICSharpCode.SharpZipLib.Core;
//using ICSharpCode.SharpZipLib.Zip;

namespace ODM_Code.Forms
{
    public partial class WriteGoogleEarthForm : Form
    {
        private string saveLocation = "";

        private IMxDocument doc;
        private IMap map;
        private IActiveView view;
        private ODM_Code.rUtils ru;

        public WriteGoogleEarthForm()
        {
            InitializeComponent();
        }

        public WriteGoogleEarthForm(IMxDocument pMxDoc)
        {
            InitializeComponent();

            doc = pMxDoc;
            map = doc.FocusMap;
            view = doc.ActivatedView;
            ru = new ODM_Code.rUtils();
        }

        private void WriteGoogleEarthForm_Load(object sender, EventArgs e)
        {
            string strTitle;

            for (int i = 0; i <= map.LayerCount - 1; i++)
            {
                if (map.get_Layer(i) == null)
                {
                    break;
                }

                strTitle = map.get_Layer(i).Name;

                string beg = strTitle.Substring(0, 2);  // Grab the first 2 characters
                string shTitle = strTitle.Substring(0, strTitle.Length - 4);

                // Sort layers into groups based on beginning characters
                if (beg.Equals("NA"))
                {
                    //naCheckedListBox.Items.Add(shTitle);
                    naCheckedListBox.Items.Add(strTitle);
                }
                else if (beg.Equals("TR") || beg.Equals("Tr"))
                {
                    //trCheckedListBox.Items.Add(shTitle);
                    trCheckedListBox.Items.Add(strTitle);
                }
                else
                {
                    //coCheckedListBox.Items.Add(shTitle);
                    coCheckedListBox.Items.Add(strTitle);
                }
                
            }

        }

        /// <summary>
        /// MainKML is the main driver for creating the final .kmz document. This creates the master kml file, 
        /// calls AddLayerToKML for each selected raster which exports the layer to PNG and updates the master kml.
        /// </summary>
        /// <returns>true if successful, false if not</returns>
        protected bool MainKML()
        {
            if (saveLoc.Text == null)
            {
                return false;
            }

            ru.SetView(view);

            saveLocation = saveLoc.Text.Substring(0, saveLoc.Text.Length - 4);
            string outKML = saveLocation + "\\doc.kml";

            ODM_Code.Forms.ProgressForm pf = new ODM_Code.Forms.ProgressForm("Starting export process.", 1, this.CountChecked(), 1);
            pf.Show();
            pf.Activate();
            pf.BringToFront();

            // Create the new folder to hold data. This will later be compressed to
            // .kmz and the source (this folder) deleted.
            if (!Directory.Exists(saveLocation))
            {
                DirectoryInfo di = Directory.CreateDirectory(saveLocation);
                //MessageBox.Show("New directory created");
            }

            // Turn off all layers
            for (int i = 0; i <= map.LayerCount - 1; i++)
            {
                map.get_Layer(i).Visible = false;
            }

            StreamWriter writer = new StreamWriter(outKML);

            pf.SetProgressLabel("Writing XML...");

            writer.WriteLine("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
            writer.WriteLine("<kml xmlns=\"http://www.opengis.net/kml/2.2\">");
            writer.WriteLine("<Document id=\"OptFuels Outputs\">");
            writer.WriteLine("  <name>OptFuels Optputs</name>");

            int itemIndex;  // Placeholder for storing index location of each checked raster relative to it's checkboxlist
            int mapIndex;   // The translated (from itemIndex) value for the raster's map layer index
            string rasName;
            string pngPath;
            //esriUtil.rasterUtil rasU = new esriUtil.rasterUtil();

            // Write each checked item from "No Action Checkbox" to master KML file
            foreach (object itemChecked in naCheckedListBox.CheckedItems)
            {
                itemIndex = naCheckedListBox.Items.IndexOf(itemChecked);
                mapIndex = ru.GetLayerIndex(map, itemChecked.ToString());  // Get index of itemChecked
                map.get_Layer(mapIndex).Visible = true;  // Turn on that layer based on index
                rasName = itemChecked.ToString();
                pngPath = ru.ExportPNG(view, saveLocation, rasName);


                pf.SetProgressLabel("Exporting " + map.get_Layer(mapIndex).Name);
                ru.AddLayerToKML(writer, map.get_Layer(mapIndex), pngPath, mapIndex);
                
                map.get_Layer(mapIndex).Visible = false;  // Turn layer off again
                pf.StepBar();
            }
            System.Threading.Thread.CurrentThread.Join(0);

            // Write each checked item from "Best Treatment Checkbox" to master KML file
            foreach (object itemChecked in trCheckedListBox.CheckedItems)
            {
                itemIndex = trCheckedListBox.Items.IndexOf(itemChecked);
                mapIndex = ru.GetLayerIndex(map, itemChecked.ToString());  // Get index of itemChecked
                map.get_Layer(mapIndex).Visible = true;  // Turn on that layer based on index
                rasName = itemChecked.ToString();
                pngPath = ru.ExportPNG(view, saveLocation, rasName);

                pf.SetProgressLabel("Exporting " + map.get_Layer(mapIndex).Name);
                ru.AddLayerToKML(writer, map.get_Layer(mapIndex), pngPath, mapIndex);
                
                map.get_Layer(mapIndex).Visible = false;  // Turn layer off again
                pf.StepBar();
            }
            System.Threading.Thread.CurrentThread.Join(0);

            // Write each checked item from "Comparison Checkbox" to master KML file
            foreach (object itemChecked in coCheckedListBox.CheckedItems)
            {
                itemIndex = coCheckedListBox.Items.IndexOf(itemChecked);
                mapIndex = ru.GetLayerIndex(map, itemChecked.ToString());  // Get index of itemChecked
                map.get_Layer(mapIndex).Visible = true;  // Turn on that layer based on index
                rasName = itemChecked.ToString();
                pngPath = ru.ExportPNG(view, saveLocation, rasName);
               
                pf.SetProgressLabel("Exporting " + map.get_Layer(mapIndex).Name);
                ru.AddLayerToKML(writer, map.get_Layer(mapIndex), pngPath, mapIndex);
                
                map.get_Layer(mapIndex).Visible = false;  // Turn layer off again
                pf.StepBar();
            }
            System.Threading.Thread.CurrentThread.Join(0);
            
            writer.WriteLine("</Document>");
            writer.WriteLine("</kml>");
            writer.Close();

            pf.SetProgressLabel("Done!");
            pf.Close();

            ///
            /// TODO: Zip package up to kmz
            ///
            pf = new ProgressForm();
            try
            {
                

            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "SharpZipLib Error");
            }

            return true;
        }

        private void browseButton_Click(object sender, EventArgs e)
        {
            //saveFileDiag.Filter = "gEarth Files (*.kml, *.kmz)|*.kml;*.kmz";
            //saveFileDiag.DefaultExt = "kmz";
            //saveFileDiag.ShowDialog();
            //saveLoc.Text = saveFileDiag.FileName;

            folderBrowseDiag.ShowDialog();
            saveLoc.Text = folderBrowseDiag.SelectedPath;
        }

        private void saveFileDiag_FileOk(object sender, CancelEventArgs e)
        {
        }

        private void openFileDiag_FileOk(object sender, CancelEventArgs e)
        { 
        }

        /// <summary>
        /// whatChecked_Click is a debugging function for using the list boxes and determining indicies
        /// </summary>
        private void whatChecked_Click(object sender, EventArgs e)
        {
            foreach (int indexChecked in naCheckedListBox.CheckedIndices)
            {
                MessageBox.Show("Index #: " + indexChecked.ToString() + ", is checked. Checked state is:" +
                    naCheckedListBox.GetItemCheckState(indexChecked).ToString() + ".");
            }

            foreach (object itemChecked in naCheckedListBox.CheckedItems)
            {
                MessageBox.Show("Item with title: \"" + itemChecked.ToString() +
                        "\", is checked. Checked state is: " +
                        naCheckedListBox.GetItemCheckState(naCheckedListBox.Items.IndexOf(itemChecked)).ToString() + ".");
            }
        }

        private void exportButton_Click(object sender, EventArgs e)
        {
            //map.SpatialReference = ru.GetGoogleProjection();
            view.Refresh();

            //bool success = this.MainKML();
            //if (success)
            //{
            //    MessageBox.Show("KMZ file successfully created.", "GEarth Exporter");
            //}
            //else
            //{
            //    MessageBox.Show("KMZ not created. Something went wrong.", "GEarth Exporter");
            //}

            // Turn off all layers
            for (int i = 0; i <= map.LayerCount - 1; i++)
            {
                map.get_Layer(i).Visible = false;
            }

            ProgressForm pf = new ProgressForm("Exporting to Google Earth", 0, this.CountChecked(), 1);
            pf.Show();
            pf.Activate();
            pf.BringToFront();

            int itemIndex;  // Placeholder for storing index location of each checked raster relative to it's checkboxlist
            int mapIndex;   // The translated (from itemIndex) value for the raster's map layer index

            try
            {
                // Write each checked item from "No Action Checkbox" to master KML file
                foreach (object itemChecked in naCheckedListBox.CheckedItems)
                {
                    itemIndex = naCheckedListBox.Items.IndexOf(itemChecked);
                    mapIndex = ru.GetLayerIndex(map, itemChecked.ToString());  // Get index of itemChecked
                    map.get_Layer(mapIndex).Visible = true;
                    pf.SetProgressLabel("Exporting " + map.get_Layer(mapIndex).Name);
                    ru.ExportToKML(map.get_Layer(mapIndex), saveLoc.Text);
                    map.get_Layer(mapIndex).Visible = false;

                    pf.StepBar();
                }

                // Write each checked item from "Best Treatment Checkbox" to master KML file
                foreach (object itemChecked in trCheckedListBox.CheckedItems)
                {
                    itemIndex = trCheckedListBox.Items.IndexOf(itemChecked);
                    mapIndex = ru.GetLayerIndex(map, itemChecked.ToString());  // Get index of itemChecked
                    map.get_Layer(mapIndex).Visible = true;
                    pf.SetProgressLabel("Exporting " + map.get_Layer(mapIndex).Name);
                    ru.ExportToKML(map.get_Layer(mapIndex), saveLoc.Text);
                    map.get_Layer(mapIndex).Visible = false;

                    pf.StepBar();
                }

                // Write each checked item from "Comparison Checkbox" to master KML file
                foreach (object itemChecked in coCheckedListBox.CheckedItems)
                {
                    itemIndex = coCheckedListBox.Items.IndexOf(itemChecked);
                    mapIndex = ru.GetLayerIndex(map, itemChecked.ToString());  // Get index of itemChecked
                    map.get_Layer(mapIndex).Visible = true;
                    pf.SetProgressLabel("Exporting " + map.get_Layer(mapIndex).Name);
                    ru.ExportToKML(map.get_Layer(mapIndex), saveLoc.Text);
                    map.get_Layer(mapIndex).Visible = false;

                    pf.StepBar();
                }
            }
            catch (Exception ex)
            {
                System.Diagnostics.Trace.WriteLine(ex.Message, "GEarth Export");
                MessageBox.Show(ex.GetType().ToString() + " :: " + ex.Message, "GEarth Export");
            }

            pf.Close();

            MessageBox.Show("Export Done.", "KMZ Export");

            //map.SpatialReference = ru.GetAlbersProjection();
            view.Refresh();

            this.Close();
        }

        private int CountChecked()
        {
            int count = 0;
            count = naCheckedListBox.CheckedItems.Count + trCheckedListBox.CheckedItems.Count + coCheckedListBox.CheckedItems.Count;
            //MessageBox.Show(count.ToString(), "Count Selected");
            return count;
        }

        private void checkNAall_CheckedChanged(object sender, EventArgs e)
        {
            if (checkNAall.Checked)
            {
                for (int i = 0; i < naCheckedListBox.Items.Count; i++)
                {
                    naCheckedListBox.SetItemChecked(i, true);
                }
            }
            else
            {
                for (int i = 0; i < naCheckedListBox.Items.Count; i++)
                {
                    naCheckedListBox.SetItemChecked(i, false);
                }
            }
        }

        private void checkTRall_CheckedChanged(object sender, EventArgs e)
        {
            if (checkTRall.Checked)
            {
                for (int i = 0; i<trCheckedListBox.Items.Count; i++)
                {
                    trCheckedListBox.SetItemChecked(i, true);
                }
            }
            else
            {
                for (int i = 0; i<trCheckedListBox.Items.Count; i++)
                {
                    trCheckedListBox.SetItemChecked(i, false);
                }
            }
        }

        private void checkCMPall_CheckedChanged(object sender, EventArgs e)
        {
            if (checkCMPall.Checked)
            {
                for (int i = 0; i < coCheckedListBox.Items.Count; i++)
                {
                    coCheckedListBox.SetItemChecked(i, true);
                }
            }
            else
            {
                for (int i = 0; i < coCheckedListBox.Items.Count; i++)
                {
                    coCheckedListBox.SetItemChecked(i, false);
                }
            }
        }

        
    }
}
